package This_Super_Overload_Override;/*
 *
 * @author 陈粒
 * @version 创建时间：2021/7/6 14:56
 */


/**
 * super的用法：子类用来调用父类非私有的方法或变量
 * 一、子类重写父类的方法，super用于调用父类的还未重写的方法(super不用放在第一行)
 * 二、子类重写父类的变量，super用于调用父类的变量，但是不能调用父类用private修饰的变量(super不用放在第一行)
 * 三、在子类的构造方法中,编译器会自动在子类的所有构造函数的第一句隐式加上super();(super必须放在第一行)
 * 当构造函数第一句为this关键字时，super语句就不会放在该构造函数中
 * 四、子类方法中，用super调用父类的非私有方法(super不用放在第一行)
 * 因此，super的作用主要在下面三种情况下：
 *
 * 1、调用父类被子类重写的方法；
 *
 * 2、调用父类被子类重定义的字段（被隐藏的成员变量）；
 *
 * 3、调用父类的构造方法；
 *
 * 4.调用父类普通方法
 * 注意：在子类的构造方法中，只要里面没有显示的通过super去调用父类相应的构造方法，
 * 默认都是调用super()，即无参构造方法，因此要确保父类有相应的构造方法。
 */
public class Super {
    public static void main(String[] args) {
        Son1 s1 = new Son1();
        s1.method1();
        System.out.println("----------------");
        Son2 s2 = new Son2();
        s2.method2();
        System.out.println("----------------");
        Son3 s3 = new Son3();//创建Fathe3类子类Son3的对象s3，创建时会调用子类Son3的无参构造函数
        System.out.println("----------------");
        Son4 s4 = new Son4();
        s4.TestS4();
    }
}

class Fathe1 {//父类1

    public void method1() {
        System.out.println("父类成员方法");
    }
}

class Son1 extends Fathe1 {
    public void method1() {//子类重写父类的方法
        System.out.println("子类成员方法");
        super.method1();//子类调用父类未重写的方法
    }
}

class Father2 {//父类2
    String s = "父类String变量";//父类变量
}

class Son2 extends Father2 {
    String s = "子类String变量";//子类重写父类变量

    public void method2() {
        System.out.println("调用子类变量：" + s);
        System.out.println("调用父类变量：" + super.s);//使用super调用父类变量
    }
}

class Father3 {
    public Father3() {
        System.out.println("父类无参构造函数");
    }

    public Father3(int a) {
        System.out.println("父类有参构造函数");
    }
}

class Son3 extends Father3 {
    public Son3() {
        this(5);//因为这里有this，所以没有隐式的super();
        System.out.println("子类无参构造函数");
    }

    public Son3(int a) {
        //这里隐式有super();用来调用父类无参构造函数
        System.out.println("子类有参构造函数");
    }
}

class Father4 {
    void TestF4() {
        System.out.println("父类普通方法");
    }
}

class Son4 extends Father4 {
    void TestS4() {
        System.out.println("子类普通方法");
        super.TestF4();//子类调用父类普通方法
    }
}

